#include "bs.h"
#include <unistd.h>
#include <err.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/types.h>
#include <sys/stat.h>

void socket_loop(void)
{
  int s;
  int client;
  struct sockaddr_in daemon_sin;
  struct sockaddr_in client_sin;
  socklen_t sa_len;
  int rc;
  int pid;
  s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if(s == -1) {
    err(EXIT_FAILURE, "socket() failed");
  }

  daemon_sin.sin_port = htons(9000);
  daemon_sin.sin_addr.s_addr = htonl(INADDR_ANY);
  daemon_sin.sin_family = AF_INET;
  rc = bind(s, (struct sockaddr *) &daemon_sin, sizeof(daemon_sin));
  if(rc == -1) {
    err(EXIT_FAILURE, "bind() failed");
  }

  rc = listen(s, SOMAXCONN);
  if(rc == -1) {
    err(EXIT_FAILURE, "listen() failed");
  }

  while(1) {
    sa_len = sizeof(struct sockaddr_in);
    client = accept4(s, (struct sockaddr *) &client_sin, &sa_len, 0);
    if(client == -1) {
      err(EXIT_FAILURE, "accept() failed");
    }
    pid = fork();
    if(pid == 0) {
      char buf[80];
      char * p;
      ssize_t count;
      size_t left;

      send(client, "hi\r\n", 4, 0);

      left = 80;
      p = buf;
      count = recv(client, buf, left, 0);
      p += count;
      left -= count;

      if(strncmp(buf, "exit", 4) == 0) {
	send(client, "bye\r\n", 5, 0);
	shutdown(client, SHUT_RDWR);
	close(client);
	exit(EXIT_SUCCESS);
      }
    }
  }
}

int main(int argc, char * argv[])
{
  int c;

  while((c = getopt(argc, argv, "v")) != -1) {
    switch(c) {
    case 'v':
      errx(EXIT_FAILURE, "BS version 0x%.08x", bs_version());
      break;
    }
  }

  socket_loop();

  return EXIT_SUCCESS;
}

